#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""统计工具

只用于学生作业评估！

统计文件（夹）大小和有效行数等
"""

import pathlib
import pyparsing


def rec(func):
    # A decorator to generate a recursive function
    # func: Path -> Number
    def f(p):
        if isinstance(p, str):
            p = pathlib.Path(p)
        if p.is_file() and p.suffix in {'.py'}:
            return func(p)
        elif p.is_dir():
            s = 0
            for q in p.iterdir():
                s += f(q)
            return s
        else:
            return 0
    return f

@rec
def size(p):
    # 统计文件大小
    # 如 print(size('tools.py'))
    if p.suffix in {'.py'}:
        return len(p.read_text())
    else:
        return 0

@rec
def code_lines(p):
    # 统计行数
    if p.suffix in {'.py'}:
        return len([a for a in p.read_text().split('\n') if a.strip()!=''])
    else:
        return 0

@rec
def comment_lines(p):
    # 统计行数
    if p.suffix in {'.py'}:
        return len([a for a in p.read_text().split('\n') if a.strip()!='' and a.strip().startswith('#')])
    else:
        return 0

@rec
def quote_lines(p):
    # 统计行数
    if p.suffix in {'.py'}:
        return len([a for a in p.read_text().split('\n') if a.strip()!='' and (a.strip().startswith("'''") or a.strip().startswith('"""'))])
    else:
        return 0

@rec
def comment_rate(p):
    if p.suffix in {'.py'}:
        if code_lines(p) ==0:
            return 0
        else:
            return comment_lines(p) / code_lines(p)
    else:
        return 0

@rec
def nfiles(p, ext={'.py', '.txt', '.xls', '.xlsx', '.md', '.yaml', '.yml', '.json', '.doc', '.docx'}):
    if p.suffix in ext:
        return 1
    else:
        return 0

@rec
def web_libs(p):
    # whether web libs are used
    if p.suffix in {'.py'}:
        t = p.read_text()
        return 'requests' in t or 'bs4' in t or 'selenium' in t or 'urllib' in t
    else:
        return 0


import re
kwds={'if':re.compile(r'\bif\b'),
'for':re.compile(r'\bfor\b'),
'while':re.compile(r'\bwhile\b'),
'def':re.compile(r'\bdef\b'),
'import':re.compile(r'\bimport\b')}

@rec
def n_keywords(p):
    # 统计关键字次数
    s = 0
    if p.suffix in {'.py'}:
        for k, x in kwds.items():
            s += len(x.findall(p.read_text()))
    return s


def ezstat(p):
    # 打印统计报告
    print('统计报告：')
    print(f'''
        大小：{size(p)}
        行数：{code_lines(p)}
        关键字数：{n_keywords(p)}
        ''')

def statx(ps, save=False):
    # 打印统计报告
    s ='''# 统计报告

|文件名 | 大小 |代码行数 | 关键字频数 | 注释行数（注释率） | 长注释次数 | 文件数量| 使用网络库|
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | --- |
'''
    paths = [p for p in ps.iterdir()]
    paths = sorted(paths, key=lambda x:x.name)
    for p in paths:
        if p.suffix=='.py' or p.is_dir():
            s += f'|{p.stem} | {size(p)} | {code_lines(p) }| {n_keywords(p)} | {comment_lines(p)}({comment_rate(p):.4%}) | {quote_lines(p)} | {nfiles(p)}| {web_libs(p)}|\n'
    print(s)
    if save:
        p = ps / 'res.md'
        p.write_text(s)

P = pathlib.Path('../网络数据/xinji17')
statx(P, True)
